#include "CaptureDeviceEnumerator.h"
#include "CaptureDevice.h"

BEGIN_DIRECTSHOWWRAPPER_NAMESPACE

CaptureDeviceEnumerator::CaptureDeviceEnumerator() :
    m_IsCaptureDeviceFound(false),
	m_IsAvailable(false),
	m_CLSID(CLSID_VideoInputDeviceCategory),
	m_pSysDevEnum(NULL),
	m_pClassEnumerator(NULL)
{
	HRESULT hr;
	hr = CoCreateInstance(CLSID_SystemDeviceEnum, 
						  NULL, 
						  CLSCTX_INPROC_SERVER,
						  IID_ICreateDevEnum, 
						  (void **)&m_pSysDevEnum);
	if(FAILED(hr))
	{
		throw _com_error(hr);
	}

	hr = m_pSysDevEnum->CreateClassEnumerator(m_CLSID, &m_pClassEnumerator, 0);
	if(hr == S_OK)
	{
		m_IsCaptureDeviceFound = true;
	}
}

CaptureDeviceEnumerator::~CaptureDeviceEnumerator()
{
	if(m_pClassEnumerator != NULL)
	{
		m_pClassEnumerator->Release();
		m_pClassEnumerator.Detach();
	}

	if(m_pSysDevEnum != NULL)
	{
		m_pSysDevEnum->Release();
		m_pSysDevEnum.Detach();
	}
}

bool CaptureDeviceEnumerator::MoveNext(CaptureDevice** ppDevice)
{
    if(m_IsCaptureDeviceFound == false)
    {
        return false;
    }

	IMoniker *pMoniker = NULL;
	ULONG cFetched;
	HRESULT hr;

	hr = m_pClassEnumerator->Next(1, &pMoniker, &cFetched);

	if(hr == S_OK)
	{
		*ppDevice = new CaptureDevice(IMonikerPtr(pMoniker));
		m_IsAvailable = true;
	}
	else
	{
		m_IsAvailable = false;
	}

	return m_IsAvailable;
}

void CaptureDeviceEnumerator::Reset()
{
    if(m_IsCaptureDeviceFound)
    {
        m_pClassEnumerator->Reset();
    }
}

END_DIRECTSHOWWRAPPER_NAMESPACE